/*
======================================================================
geometry.c

Ernie Wright  24 Jan 00

This stores the geometry data used by the dna.p Modeler plug-in to
construct DNA molecules.  Like real DNA, the model is built up from
base units that connect together to form the molecule.  Each base
unit connects to the one below it after a Y translation of 3.4 and a
Y rotation of 36 degrees.  Each base is made of a purine-pyrimidine
pair plus fragments of phosphate backbone.

A base unit is defined by a list of vertices and by indexes into the
vertex list for atoms, bonds and plates.  A plate is a pair of semi-
transparent polygons that fill in the space between the atoms of the
purine and pyrimidine molecules.

Access to this data is provided through functions.
====================================================================== */

#include <stdio.h>
#include <math.h>
#include "geometry.h"


typedef struct { float x, y, z; }                 POINT3;
typedef struct { unsigned char vi, si; }          PATOM;
typedef struct { unsigned char vi[ 2 ], si; }     PBOND;
typedef struct { unsigned char nv, si, vi[ 9 ]; } PPLATE;

typedef struct {
   POINT3 *vert;
   PATOM  *atom;
   PBOND  *bond;
   PPLATE *plate;
   int    natoms;
   int    nbonds;
   int    npoints;
} DNA_BASE;


/* surface data */

DNA_SURFACE surfdata[ 11 ] = {
   { "DNA Atom C",
     0.000f, 0.518f, 0.275f, 1.0f, 0.6f, 0.6f, 1.562f, 0.0f, 1.0f, 1 },
   { "DNA Atom H",
     0.969f, 0.451f, 0.000f, 1.0f, 0.6f, 0.6f, 1.562f, 0.0f, 1.0f, 1 },
   { "DNA Atom N",
     0.325f, 0.569f, 1.000f, 1.0f, 0.6f, 0.6f, 1.562f, 0.0f, 1.0f, 1 },
   { "DNA Atom O",
     1.000f, 0.102f, 0.173f, 1.0f, 0.6f, 0.6f, 1.562f, 0.0f, 1.0f, 1 },
   { "DNA Atom P",
     0.784f, 0.784f, 0.784f, 1.0f, 0.6f, 0.6f, 1.562f, 0.0f, 1.0f, 1 },
   { "DNA Bond",
     0.392f, 0.392f, 0.392f, 1.0f, 0.6f, 0.6f, 1.562f, 0.0f, 1.0f, 1 },
   { "DNA Bond H",
     0.569f, 0.400f, 0.251f, 1.0f, 0.6f, 0.6f, 1.562f, 0.0f, 1.0f, 1 },
   { "DNA Plate Adenine",
     0.784f, 0.392f, 0.784f, 1.0f, 0.0f, 0.0f, 0.000f, 0.7f, 1.0f, 3 },
   { "DNA Plate Cytosine",
     0.392f, 0.784f, 0.392f, 1.0f, 0.0f, 0.0f, 0.000f, 0.7f, 1.0f, 3 },
   { "DNA Plate Guanine",
     0.392f, 0.392f, 0.784f, 1.0f, 0.0f, 0.0f, 0.000f, 0.7f, 1.0f, 3 },
   { "DNA Plate Thymine",
     0.784f, 0.392f, 0.392f, 1.0f, 0.0f, 0.0f, 0.000f, 0.7f, 1.0f, 3 }
};

/* adenine vertex list */

static POINT3 avert[ 54 ] = {
    8.590569f, -3.900000f, -4.395965f,
    8.888400f, -2.800000f, -3.627300f,
    3.442563f, -7.800000f,  9.015052f,
    4.178231f, -8.900000f,  8.643109f,
   10.000000f,  0.000000f,  0.000000f,
    8.932300f,  0.800000f, -0.562000f,
   11.249200f,  0.800000f,  0.137400f,
    9.533800f, -0.500000f,  1.493000f,
   10.305800f, -1.300000f, -0.956000f,
    8.888400f, -2.800000f, -3.627300f,
    9.395000f, -3.200000f, -2.203600f,
    9.125400f, -2.050000f, -1.169000f,
    8.649800f, -2.800000f,  0.060400f,
    8.184700f, -4.150000f, -0.500600f,
    8.614000f, -4.350000f, -1.799600f,
    2.079117f, -8.300000f,  9.781476f,
    1.307411f, -9.099999f,  8.853954f,
    2.473238f, -9.099999f, 10.974811f,
    3.442563f, -7.800000f,  9.015052f,
    1.207587f, -7.000000f, 10.279358f,
   -1.700033f, -5.500000f,  9.448325f,
   -0.202116f, -5.100000f,  9.647852f,
    0.753823f, -6.250000f,  9.169037f,
    1.857475f, -5.500000f,  8.448223f,
    1.212034f, -4.150000f,  8.109925f,
    0.030677f, -3.950000f,  8.799922f,
   -1.196934f, -4.150000f,  6.290834f,
   -0.432944f, -4.150000f,  5.859887f,
    0.868939f, -4.150000f,  6.446927f,
   -0.238220f, -4.150000f,  4.473960f,
    1.679139f, -4.150000f,  5.402325f,
    1.059460f, -4.150000f,  4.240736f,
    2.998375f, -4.150000f,  5.438077f,
    1.139875f, -4.150000f,  1.937958f,
    1.759356f, -4.150000f,  3.105214f,
    3.078268f, -4.150000f,  3.150240f,
    3.697932f, -4.150000f,  4.312241f,
    4.676965f, -4.150000f,  4.341271f,
    4.139171f, -4.150000f,  1.425678f,
    1.686142f, -4.150000f,  1.065913f,
    2.724292f, -4.150000f, -0.597957f,
    4.043529f, -4.150000f, -0.562205f,
    4.663208f, -4.150000f,  0.599384f,
    5.982442f, -4.150000f,  0.635137f,
    6.601942f, -4.150000f,  1.801877f,
    4.743424f, -4.150000f, -1.697727f,
    6.062659f, -4.150000f, -1.661975f,
    6.682000f, -4.150000f, -0.490700f,
    6.586739f, -4.150000f, -2.489505f,
    0.160842f, -4.150000f,  1.908927f,
    3.868400f, -3.301295f, -3.283952f,
    4.504929f, -4.574352f, -3.651453f,
    4.113400f, -4.150000f, -2.859600f,
    3.231871f, -4.574352f, -2.916452f
};

/* cytosine vertex list */

static POINT3 cvert[ 53 ] = {
    8.590569f, -3.900000f, -4.395965f,
    8.888400f, -2.800000f, -3.627300f,
    3.442563f, -7.800000f,  9.015052f,
    4.178231f, -8.900000f,  8.643109f,
   10.000000f,  0.000000f,  0.000000f,
    8.932300f,  0.800000f, -0.562000f,
   11.249200f,  0.800000f,  0.137400f,
    9.533800f, -0.500000f,  1.493000f,
   10.305800f, -1.300000f, -0.956000f,
    8.888400f, -2.800000f, -3.627300f,
    9.395000f, -3.200000f, -2.203600f,
    9.125400f, -2.050000f, -1.169000f,
    8.649800f, -2.800000f,  0.060400f,
    8.184700f, -4.150000f, -0.500600f,
    8.614000f, -4.350000f, -1.799600f,
    6.682000f, -4.150000f, -0.490700f,
    2.079117f, -8.300000f,  9.781476f,
    1.307411f, -9.099999f,  8.853954f,
    2.473238f, -9.099999f, 10.974811f,
    3.442563f, -7.800000f,  9.015052f,
    1.207587f, -7.000000f, 10.279358f,
   -1.700033f, -5.500000f,  9.448325f,
   -0.202116f, -5.100000f,  9.647852f,
    0.753823f, -6.250000f,  9.169037f,
    1.857475f, -5.500000f,  8.448223f,
    1.212034f, -4.150000f,  8.109925f,
    0.030677f, -3.950000f,  8.799922f,
    0.869289f, -4.150000f,  6.438005f,
    6.172489f, -4.150000f, -2.499571f,
    5.875313f, -4.150000f, -1.669380f,
    4.558532f, -4.150000f, -1.246361f,
    5.795819f, -4.150000f,  0.498465f,
    4.531262f, -4.150000f,  0.075084f,
    6.055146f, -4.150000f,  1.778549f,
    2.279248f, -4.150000f,  0.565389f,
    3.550793f, -4.150000f,  0.970327f,
    3.809247f, -4.150000f,  2.265071f,
    5.066425f, -4.150000f,  2.673890f,
    5.331867f, -4.150000f,  3.930190f,
    0.824405f, -4.150000f,  1.885680f,
    3.076748f, -4.150000f,  2.913129f,
    0.062874f, -4.150000f,  2.557914f,
    0.331039f, -4.150000f,  3.857320f,
    1.582876f, -4.150000f,  4.267013f,
    1.851042f, -4.150000f,  5.546419f,
    3.099871f, -4.150000f,  5.967084f,
   -1.582238f, -4.150000f,  4.429280f,
   -0.663119f, -4.150000f,  4.745283f,
   -0.406606f, -4.150000f,  6.032843f,
   -1.121547f, -4.150000f,  6.684883f,
    4.660000f, -4.150000f,  4.530000f,
   -0.720000f, -4.150000f,  2.320000f,
    6.260000f, -4.150000f,  4.240000f
};

/* guanine vertex list */

static POINT3 gvert[ 53 ] = {
    8.590569f, -3.900000f, -4.395965f,
    8.888400f, -2.800000f, -3.627300f,
    3.442563f, -7.800000f,  9.015052f,
    4.178231f, -8.900000f,  8.643109f,
   10.000000f,  0.000000f,  0.000000f,
    8.932300f,  0.800000f, -0.562000f,
   11.249200f,  0.800000f,  0.137400f,
    9.533800f, -0.500000f,  1.493000f,
   10.305800f, -1.300000f, -0.956000f,
    8.888400f, -2.800000f, -3.627300f,
    9.395000f, -3.200000f, -2.203600f,
    9.125400f, -2.050000f, -1.169000f,
    8.649800f, -2.800000f,  0.060400f,
    8.184700f, -4.150000f, -0.500600f,
    8.614000f, -4.350000f, -1.799600f,
    2.079117f, -8.300000f,  9.781476f,
    1.307411f, -9.099999f,  8.853954f,
    2.473238f, -9.099999f, 10.974811f,
    3.442563f, -7.800000f,  9.015052f,
    1.207587f, -7.000000f, 10.279358f,
   -1.700033f, -5.500000f,  9.448325f,
   -0.202116f, -5.100000f,  9.647852f,
    0.753823f, -6.250000f,  9.169037f,
    1.857475f, -5.500000f,  8.448223f,
    1.212034f, -4.150000f,  8.109925f,
    0.030677f, -3.950000f,  8.799922f,
    0.869289f, -4.150000f,  6.438005f,
    6.682000f, -4.150000f, -0.490700f,
   -1.207477f, -4.150000f,  6.302115f,
   -0.433410f, -4.150000f,  5.864733f,
   -0.231578f, -4.150000f,  4.475911f,
    1.669578f, -4.150000f,  5.397439f,
    1.070642f, -4.150000f,  4.240271f,
    3.007336f, -4.150000f,  5.446844f,
    1.153921f, -4.150000f,  1.938541f,
    1.761598f, -4.150000f,  3.106779f,
    3.087607f, -4.150000f,  3.156087f,
    3.699164f, -4.150000f,  4.318692f,
    4.993914f, -4.150000f,  4.359071f,
    2.014007f, -4.150000f,  0.529125f,
    3.583212f, -4.150000f,  2.335218f,
    2.718645f, -4.150000f, -0.595919f,
    4.038052f, -4.150000f, -0.564084f,
    4.669706f, -4.150000f,  0.606773f,
    5.989112f, -4.150000f,  0.638608f,
    6.606883f, -4.150000f,  1.805681f,
    4.290944f, -4.150000f, -2.529402f,
    4.735317f, -4.150000f, -1.704856f,
    6.068511f, -4.150000f, -1.657489f,
    6.593936f, -4.150000f, -2.487777f,
    5.446875f, -4.150000f,  3.620038f,
    2.120000f, -4.150000f, -1.380000f,
    5.539999f, -4.150000f,  5.360000f
};

/* thymine vertex list */

static POINT3 tvert[ 54 ] = {
    6.169553f, -4.150000f, -2.498083f,
    5.877817f, -4.150000f, -1.670866f,
    6.682008f, -4.150000f, -0.490700f,
    4.546760f, -4.150000f, -1.238436f,
    5.793967f, -4.150000f,  0.488585f,
    4.542418f, -4.150000f,  0.080028f,
    6.058259f, -4.150000f,  1.781570f,
    2.288589f, -4.150000f,  0.559094f,
    3.545683f, -4.150000f,  0.966472f,
    3.819051f, -4.150000f,  2.257528f,
    5.071003f, -4.150000f,  2.665998f,
    5.269600f, -4.150000f,  3.625117f,
    2.304914f, -4.150000f,  3.601780f,
    1.524650f, -4.150000f,  1.248491f,
    0.066331f, -4.150000f,  2.559797f,
    0.330623f, -4.150000f,  3.852783f,
    1.582171f, -4.150000f,  4.261340f,
    1.846463f, -4.150000f,  5.554325f,
    3.103054f, -4.150000f,  5.961810f,
   -0.666112f, -4.150000f,  4.739227f,
   -0.401820f, -4.150000f,  6.032212f,
    0.859207f, -4.150000f,  6.438754f,
   -1.125773f, -4.150000f,  6.692029f,
    2.089992f, -4.150000f, -0.400024f,
   -2.380186f, -3.301295f,  4.152942f,
   -2.631570f, -4.574352f,  4.843616f,
   -1.919737f, -4.150000f,  4.320532f,
   -2.128801f, -4.574352f,  3.462268f,
    8.590569f, -3.900000f, -4.395965f,
    8.888400f, -2.800000f, -3.627300f,
    3.442563f, -7.800000f,  9.015052f,
    4.178231f, -8.900000f,  8.643109f,
   10.000000f,  0.000000f,  0.000000f,
    8.932300f,  0.800000f, -0.562000f,
   11.249200f,  0.800000f,  0.137400f,
    9.533800f, -0.500000f,  1.493000f,
   10.305800f, -1.300000f, -0.956000f,
    8.888400f, -2.800000f, -3.627300f,
    9.395000f, -3.200000f, -2.203600f,
    9.125400f, -2.050000f, -1.169000f,
    8.649800f, -2.800000f,  0.060400f,
    8.184700f, -4.150000f, -0.500600f,
    8.614000f, -4.350000f, -1.799600f,
    2.079117f, -8.300000f,  9.781476f,
    1.307411f, -9.099999f,  8.853954f,
    2.473238f, -9.099999f, 10.974811f,
    3.442563f, -7.800000f,  9.015052f,
    1.207587f, -7.000000f, 10.279358f,
   -1.700033f, -5.500000f,  9.448325f,
   -0.202116f, -5.100000f,  9.647852f,
    0.753823f, -6.250000f,  9.169037f,
    1.857475f, -5.500000f,  8.448223f,
    1.212034f, -4.150000f,  8.109925f,
    0.030677f, -3.950000f,  8.799922f
};

/* atoms:  index into the vertex list, atom ID */
/* adenine */

static PATOM aatom[ 50 ] = {
   52, 0,   53, 1,   50, 1,   51, 1,   49, 1,
   47, 2,   48, 1,   46, 0,   45, 0,   44, 3,
   43, 0,   42, 2,   41, 0,   40, 3,   39, 1,
   38, 1,   37, 1,   36, 0,   35, 2,   34, 0,
   33, 2,   32, 2,   30, 0,   31, 0,   29, 2,
   28, 2,   27, 0,   26, 1,    4, 4,    5, 3,
    6, 3,    7, 3,    8, 3,   11, 0,    9, 0,
   10, 0,   14, 3,   13, 0,   12, 0,   23, 0,
   24, 0,   25, 3,   21, 0,   20, 0,   22, 0,
   19, 3,   18, 3,   17, 3,   16, 3,   15, 4
};

/* cytosine */

static PATOM catom[ 49 ] = {
   52, 1,   51, 1,   28, 1,   29, 0,   15, 2,
   30, 2,   33, 2,   31, 0,   32, 0,   38, 2,
   37, 0,   36, 2,   35, 0,   34, 3,   39, 1,
   45, 3,   50, 1,   40, 1,   41, 2,   44, 0,
   43, 2,   42, 0,   46, 1,   47, 0,   49, 1,
   48, 0,   27, 2,   16, 4,   17, 3,   18, 3,
   19, 3,   20, 3,   23, 0,   21, 0,   22, 0,
   26, 3,   25, 0,   24, 0,   12, 0,   13, 0,
   14, 3,   10, 0,    9, 0,   11, 0,    8, 3,
    7, 3,    6, 3,    5, 3,    4, 4
};

/* guanine */

static PATOM gatom[ 49 ] = {
   52, 1,   51, 1,   27, 2,   48, 0,   49, 1,
   47, 0,   46, 1,   42, 0,   43, 2,   44, 0,
   41, 2,   40, 1,   50, 1,   45, 3,   39, 1,
   34, 3,   35, 0,   36, 2,   37, 0,   38, 2,
   32, 0,   31, 0,   33, 2,   30, 2,   26, 2,
   29, 0,   28, 1,    4, 4,    5, 3,    6, 3,
    7, 3,    8, 3,   11, 0,    9, 0,   10, 0,
   14, 3,   13, 0,   12, 0,   23, 0,   24, 0,
   25, 3,   21, 0,   20, 0,   22, 0,   19, 3,
   18, 3,   17, 3,   16, 3,   15, 4
};

/* thymine */

static PATOM tatom[ 50 ] = {
    0, 1,    1, 0,    2, 2,    3, 2,    5, 0,
    4, 0,    6, 2,    7, 2,    8, 0,    9, 2,
   10, 0,   11, 1,   12, 1,   13, 1,   14, 3,
   15, 0,   16, 2,   17, 0,   18, 3,   19, 0,
   20, 0,   22, 1,   21, 2,   23, 1,   25, 1,
   24, 1,   27, 1,   26, 0,   32, 4,   33, 3,
   34, 3,   35, 3,   36, 3,   39, 0,   37, 0,
   38, 0,   42, 3,   41, 0,   40, 0,   51, 0,
   52, 0,   53, 3,   49, 0,   48, 0,   50, 0,
   47, 3,   46, 3,   45, 3,   44, 3,   43, 4
};

/* bonds:  2 indexes into the vertex list, bond ID */
/* adenine */

static PBOND abond[ 57 ] = {
   45, 52, 5,   52, 50, 5,   52, 51, 5,   52, 53, 5,   28, 24, 5,
   47, 13, 5,   49, 33, 5,   38, 42, 5,   33, 39, 5,   46, 48, 5,
   45, 41, 5,   46, 45, 5,   47, 46, 5,   43, 47, 5,   43, 44, 5,
   42, 43, 5,   41, 42, 5,   40, 41, 5,   39, 40, 6,   35, 38, 6,
   34, 33, 5,   36, 37, 5,   32, 30, 5,   36, 32, 5,   35, 36, 5,
   34, 35, 5,   31, 34, 5,   28, 27, 5,   30, 28, 5,   31, 30, 5,
   29, 31, 5,   27, 29, 5,   26, 27, 5,    0,  1, 5,    3,  2, 5,
    9, 10, 5,   11, 10, 5,   10, 14, 5,   14, 13, 5,   13, 12, 5,
   12, 11, 5,    8, 11, 5,    4,  8, 5,    4,  7, 5,    5,  4, 5,
    6,  4, 5,   17, 15, 5,   16, 15, 5,   15, 18, 5,   15, 19, 5,
   19, 22, 5,   23, 22, 5,   24, 23, 5,   25, 24, 5,   21, 25, 5,
   22, 21, 5,   20, 21, 5
};

/* cytosine */

static PBOND cbond[ 57 ] = {
   52, 38, 5,   51, 41, 5,    0,  1, 5,    3,  2, 5,   50, 38, 5,
   50, 45, 6,   15, 29, 5,   31, 15, 5,   27, 44, 5,   48, 27, 5,
   28, 29, 5,   31, 32, 5,   32, 30, 5,   30, 29, 5,   31, 33, 5,
   33, 37, 5,   37, 36, 5,   36, 35, 5,   35, 32, 5,   35, 34, 5,
   37, 38, 5,   34, 39, 6,   40, 43, 6,   43, 42, 5,   42, 47, 5,
   47, 48, 5,   44, 43, 5,   47, 46, 5,   48, 49, 5,   42, 41, 5,
   44, 45, 5,   39, 41, 5,   36, 40, 5,   21, 22, 5,   27, 25, 5,
   23, 22, 5,   22, 26, 5,   26, 25, 5,   25, 24, 5,   24, 23, 5,
   20, 23, 5,   16, 20, 5,   16, 19, 5,   17, 16, 5,   18, 16, 5,
    6,  4, 5,    5,  4, 5,    4,  7, 5,    4,  8, 5,    8, 11, 5,
   12, 11, 5,   13, 12, 5,   14, 13, 5,   10, 14, 5,   11, 10, 5,
   15, 13, 5,    9, 10, 5
};

/* guanine */

static PBOND gbond[ 57 ] = {
   52, 38, 5,   51, 41, 5,    0,  1, 5,    3,  2, 5,   24, 26, 5,
   27, 13, 5,   36, 40, 5,   39, 41, 5,   44, 45, 5,   42, 41, 5,
   48, 49, 5,   47, 46, 5,   44, 43, 5,   47, 48, 5,   42, 47, 5,
   43, 42, 5,   40, 43, 6,   34, 39, 6,   37, 38, 5,   35, 34, 5,
   35, 32, 5,   36, 35, 5,   37, 36, 5,   33, 37, 5,   31, 33, 5,
   30, 29, 5,   32, 30, 5,   31, 32, 5,   28, 29, 5,   48, 27, 5,
   27, 44, 5,   31, 26, 5,   26, 29, 5,   50, 45, 6,   50, 38, 5,
    9, 10, 5,   11, 10, 5,   10, 14, 5,   14, 13, 5,   13, 12, 5,
   12, 11, 5,    8, 11, 5,    4,  8, 5,    4,  7, 5,    5,  4, 5,
    6,  4, 5,   17, 15, 5,   16, 15, 5,   15, 18, 5,   15, 19, 5,
   19, 22, 5,   23, 22, 5,   24, 23, 5,   25, 24, 5,   21, 25, 5,
   22, 21, 5,   20, 21, 5
};

/* thymine */

static PBOND tbond[ 57 ] = {
   21, 52, 5,    2, 41, 5,    0,  1, 5,    1,  3, 5,    3,  5, 5,
    5,  4, 5,    4,  2, 5,    2,  1, 5,    5,  8, 5,    8,  9, 5,
    9, 10, 5,   10,  6, 5,    6,  4, 5,   10, 11, 5,    8,  7, 5,
    9, 12, 6,   13, 14, 6,   14, 15, 5,   15, 16, 5,   16, 17, 5,
   17, 18, 5,   17, 21, 5,   21, 20, 5,   20, 19, 5,   19, 15, 5,
   20, 22, 5,    7, 13, 5,   12, 16, 5,   23,  7, 5,   26, 27, 5,
   26, 25, 5,   26, 24, 5,   19, 26, 5,   28, 29, 5,   31, 30, 5,
   37, 38, 5,   39, 38, 5,   38, 42, 5,   42, 41, 5,   41, 40, 5,
   40, 39, 5,   36, 39, 5,   32, 36, 5,   32, 35, 5,   33, 32, 5,
   34, 32, 5,   45, 43, 5,   44, 43, 5,   43, 46, 5,   43, 47, 5,
   47, 50, 5,   51, 50, 5,   52, 51, 5,   53, 52, 5,   49, 53, 5,
   50, 49, 5,   48, 49, 5
};

/* plate:  vertex count, surface ID, vertex indexes for 2 polygons */

static PPLATE aplate[ 2 ] = {
   { 6, 10,  43, 47, 46, 45, 41, 42 },
   { 9,  7,  28, 30, 32, 36, 35, 34, 31, 29, 27 }
};

static PPLATE cplate[ 2 ] = {
   { 9,  9,  37, 33, 31, 15, 29, 30, 32, 35, 36 },
   { 6,  8,  27, 44, 43, 42, 47, 48 }
};

static PPLATE gplate[ 2 ] = {
   { 6,  8,  44, 27, 48, 47, 42, 43 },
   { 9,  9,  26, 31, 33, 37, 36, 35, 32, 30, 29 }
};

static PPLATE tplate[ 2 ] = {
   { 9,  7,   1,  3,  5,  8,  9, 10,  6,  4,  2 },
   { 6, 10,  16, 15, 19, 20, 21, 17 }
};

/* bases */

static DNA_BASE base[ 4 ] = {
   { avert, aatom, abond, aplate, 50, 57, 54 },
   { cvert, catom, cbond, cplate, 49, 57, 53 },
   { gvert, gatom, gbond, gplate, 49, 57, 53 },
   { tvert, tatom, tbond, tplate, 50, 57, 54 }
};


/*
======================================================================
atom_count()
bond_count()
point_count()

Return the numbers of atoms, bonds, and points for a given base.
====================================================================== */

int atom_count( int ibase )
{
   return base[ ibase ].natoms;
}


int bond_count( int ibase )
{
   return base[ ibase ].nbonds;
}


int point_count( int ibase )
{
   return base[ ibase ].npoints;
}


/*
======================================================================
atom_info()

Return the vertex index and surface ID for an atom of a given base.
====================================================================== */

void atom_info( int ibase, int iatom, int *vi, int *snum )
{
   *vi   = base[ ibase ].atom[ iatom ].vi;
   *snum = base[ ibase ].atom[ iatom ].si;
}


/*
======================================================================
bond_info()

Return two vertex indexes and a surface ID for a bond of a given base.
====================================================================== */

void bond_info( int ibase, int ibond, int *vi0, int *vi1, int *snum )
{
   *vi0  = base[ ibase ].bond[ ibond ].vi[ 0 ];
   *vi1  = base[ ibase ].bond[ ibond ].vi[ 1 ];
   *snum = base[ ibase ].bond[ ibond ].si;
}


/*
======================================================================
plate_info()

Return vertex indexes and a surface ID for a plate polygon.
====================================================================== */

void plate_info( int ibase, int iplate, int *nv, int *vi, int *snum )
{
   int i;

   *nv = base[ ibase ].plate[ iplate ].nv;
   for ( i = 0; i < *nv; i++ )
      vi[ i ] = base[ ibase ].plate[ iplate ].vi[ i ];
   *snum = base[ ibase ].plate[ iplate ].si;
}


/*
======================================================================
vert_coords()

Return coordinates for a point from a given base.
====================================================================== */

void vert_coords( int ibase, int ivert, double pt[ 3 ] )
{
   pt[ 0 ] = base[ ibase ].vert[ ivert ].x;
   pt[ 1 ] = base[ ibase ].vert[ ivert ].y;
   pt[ 2 ] = base[ ibase ].vert[ ivert ].z;
}


/*
======================================================================
bond_coords()

Return coordinates for one end of a bond, the bond's length and
direction, and the surface index.  The direction is given as rotations
in degrees around the X and Y axes.
====================================================================== */

void bond_coords( int ibase, int ibond, double pt[ 3 ], double *h,
   double *xrot, double *yrot, int *snum )
{
   double dx, dy, dz;

   pt[ 0 ] = base[ ibase ].vert[ base[ ibase ].bond[ ibond ].vi[ 0 ]].x;
   pt[ 1 ] = base[ ibase ].vert[ base[ ibase ].bond[ ibond ].vi[ 0 ]].y;
   pt[ 2 ] = base[ ibase ].vert[ base[ ibase ].bond[ ibond ].vi[ 0 ]].z;
   dx = base[ ibase ].vert[ base[ ibase ].bond[ ibond ].vi[ 1 ]].x - pt[ 0 ];
   dy = base[ ibase ].vert[ base[ ibase ].bond[ ibond ].vi[ 1 ]].y - pt[ 1 ];
   dz = base[ ibase ].vert[ base[ ibase ].bond[ ibond ].vi[ 1 ]].z - pt[ 2 ];
   *h = sqrt( dx * dx + dy * dy + dz * dz );
   *xrot = raddeg( acos( dy / *h ));
   *yrot = 90.0 + raddeg( atan2( dz, dx ));
   *snum = base[ ibase ].bond[ ibond ].si;
}


/*
======================================================================
surface_data()
surface_name()

Return information about the surfaces.
====================================================================== */

DNA_SURFACE *surface_data( int snum )
{
   return &surfdata[ snum ];
}


char *surface_name( int snum )
{
   return surfdata[ snum ].name;
}
